package com.qishenyuan.competition.utils;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Jacky
 * @since 2025-03-04
 */
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Locale;

@Slf4j
public class DateUtil {

    public static final String FORMAT = "yyyyMMdd HH:mm:ss";

    public static final String FORMAT_WITH_SPLIT = "yyyy-MM-dd HH:mm:ss";

    public static final String FORMAT_YYYYMMDDHH_MM_SS_SSS = "yyyyMMdd HH:mm:ss:SSS";

    public static final String CLEAR_FORMAT = "yyyyMMddHHmmss";

    public static final String FORMAT_YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";

    public static final String FORMAT_YYYYMMDD = "yyyyMMdd";

    public static final String FORMAT_DDMMMYYYY = "dd MMM yyyy";

    public static final String FORMAT_DDMMMYYYYHHMM = "dd MMM yyyy HH:mm";

    public static final String FORMAT_YYYY_MM_DD = "yyyy-MM-dd";



    public static String format(long timestamp, String pattern) {
        return format(new Date(timestamp), pattern);
    }

    /**
     * 格式化时间.
     *
     * @param date    日期
     * @param pattern 日期格式
     * @return 格式后的日期.
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(date);
    }

    /**
     * 格式化时间.
     *
     * @param date     日期.
     * @param pattern  日期格式.
     * @param language 语言
     * @return 格式后的日期.
     */
    public static String formatWithLanguage(Date date, String pattern, Locale language) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, language);
        return simpleDateFormat.format(date);
    }

    /**
     * 时间字符转时间戳
     *
     * @param time    时间字符.
     * @param pattern 时间格式.
     * @return 时间戳.
     */
    public static Long parseTimeToLong(String time, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            Date date = format.parse(time);
            return date.getTime();
        } catch (ParseException e) {
            log.warn(String.format("date parse error [time=%s][pattern=%s]", time, pattern), e);
        }
        return null;
    }

    /**
     * 解析日期.
     *
     * @param date    日期字符串.
     * @param pattern 日期格式.
     * @return 解析得到的日期.
     */
    public static Date parse(String date, String pattern) {
        try {
            return DateUtils.parseDate(date, pattern);
        } catch (ParseException e) {
            log.warn(String.format("date parse error [date=%s][pattern=%s]", date, pattern), e);
        }
        return null;
    }

    /**
     * 解析日期
     * @param date
     * @param pattern
     * @param language
     * @return
     */
    public static Date parseWithLanguage(String date, String pattern,Locale language) {
        SimpleDateFormat format = new SimpleDateFormat(pattern, language);
        try {
            return format.parse(date);
        } catch (ParseException e) {
            log.warn(String.format("date parse error [date=%s][pattern=%s][language=%s]", date, pattern,language), e);
        }
        return null;
    }


    /**
     * 获取指定日期当天的最后一秒时间.
     *
     * @param date 日期.
     * @return 日期当天的最后一秒时间
     */
    public static Date getDayLastSecondTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        return calendar.getTime();
    }

    /**
     * 获取指定日期当天的第一秒时间.
     *
     * @param date 日期.
     * @return 日期当天的第一秒时间
     */
    public static Date getDayFirstSecondTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        return calendar.getTime();
    }


    /**
     * 根据时间戳字符串格式化时间
     *
     * @param timestamp 时间戳字符串
     * @param pattern       时间格式
     * @return 格式后的日期
     */
    public static String formatByTimestamp(String timestamp, String pattern) {
        try {
            long dateTimestamp = Long.parseLong(timestamp);
            return format(new Date(dateTimestamp), pattern);
        } catch (Exception e) {
            log.warn(String.format("timestamp format error [timestamp=%s][pattern=%s]", timestamp, pattern), e);
        }
        return null;
    }



    /**
     * 获取指定时间间隔year的时间
     * @param date
     * @param year
     * @param pattern
     * @return
     */
    public static String getDayBeforeYear(Date date, int year, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return sdf.format(calendar.getTime());
    }

    /**
     * 获取指定时间间隔day的时间
     * @param date
     * @param days
     * @param pattern
     * @return
     */
    public static String getDateBeforeDays(Date date, int days, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, (-1) * days);
        return sdf.format(calendar.getTime());
    }
    public static long getSpecifiedDaysAfterTime(long timeStamp, int intervalDays){
        Calendar assignedEndTime = Calendar.getInstance();
        assignedEndTime.setTime(new Date(timeStamp));
        assignedEndTime.add(Calendar.DAY_OF_MONTH, intervalDays);
        return assignedEndTime.getTimeInMillis();
    }

    public static Date getSpecifiedDaysAfterStartTime(Date date, int intervalDays) {
        Calendar assignedStartTime = Calendar.getInstance();
        assignedStartTime.setTime(date);
        assignedStartTime.set(Calendar.HOUR_OF_DAY, 0);
        assignedStartTime.set(Calendar.MINUTE, 0);
        assignedStartTime.set(Calendar.SECOND, 0);
        assignedStartTime.set(Calendar.MILLISECOND, 0);
        assignedStartTime.add(Calendar.DAY_OF_MONTH,  intervalDays);
        return assignedStartTime.getTime();
    }
    public static Date getSpecifiedDaysAfterEndTime(Date date, int intervalDays) {
        Calendar assignedEndTime = Calendar.getInstance();
        assignedEndTime.setTime(date);
        assignedEndTime.set(Calendar.HOUR_OF_DAY, 23);
        assignedEndTime.set(Calendar.MINUTE, 59);
        assignedEndTime.set(Calendar.SECOND, 59);
        assignedEndTime.set(Calendar.MILLISECOND, 999);
        assignedEndTime.add(Calendar.DAY_OF_MONTH, intervalDays);
        return assignedEndTime.getTime();
    }

}
